using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.IO;

namespace Lizard.Remoting.TFAccess
{

	public class ReviewRowColumns
	{
		public string LocalItem;
		public int Version;
		public int LatestVersion;
		public string ChangeTypeText;
		public string ConflictBaseChangeType;
		public string ConflictBriefMessage;
		public ItemType ItemType;
		public string ItemPath;
		public TFInfoSet InfoSet;
		public bool IsRenamed = false;
		public string OldName;
		public string Location;
		public string MainText;
		public string ImageKey;
		public string StateImage;
		public bool HasCheckbox=false;


		public ReviewRowColumns()
		{ }

		public ReviewRowColumns(TFInfoSet infoset)
		{
			InfoSet = infoset;
			LocalItem = infoset.ExtendedItem.LocalItem;
			Version = infoset.ExtendedItem.VersionLocal;
			LatestVersion = infoset.ExtendedItem.VersionLatest;
			ChangeTypeText = infoset.ExtendedItem.ChangeType.ToString();
			ItemType = infoset.ExtendedItem.ItemType;
			HasCheckbox = true;
			if (infoset.Conflict != null)
			{
				ConflictBaseChangeType = infoset.Conflict.BaseChangeType.ToString();
				ConflictBriefMessage = infoset.Conflict.GetBriefMessage();
			}
			else
			{
				ConflictBaseChangeType = "-";
				ConflictBriefMessage = "-";
			}
			if (((infoset.ExtendedItem.ChangeType & ChangeType.Rename) == ChangeType.Rename) 
				|| ((infoset.ExtendedItem.ChangeType & ChangeType.Branch) == ChangeType.Branch))
			{
				ItemPath = infoset.ExtendedItem.TargetServerItem;
				OldName = infoset.ExtendedItem.SourceServerItem;
				IsRenamed = true;
			}
			else
			{
				ItemPath = infoset.ExtendedItem.SourceServerItem;
			}
			if (ItemType == ItemType.File)
			{
				MainText = Path.GetFileName(ItemPath);
				ImageKey = null;
			}
			else
			{
				MainText = ItemPath;
				ImageKey = "$folder";
			}
			if (ItemType==ItemType.Folder)
				Location = ItemPath.Replace("/", "\\");
			else
				Location = Path.GetDirectoryName(ItemPath);

		}
	}

	public class TFInfoSet
	{
		public Item Item;
		public ExtendedItem ExtendedItem;
		public PendingChange PendingChange;
		public Conflict Conflict;


		public TFInfoSet(Item item, ExtendedItem extItem, PendingChange pendingChange, Conflict conflict)
		{
			Item = item;
			ExtendedItem = extItem;
			PendingChange = pendingChange;
			Conflict = conflict;
		}

		public TFInfoSet()
		{ }
	}

	public class LizardTFItems
	{
		Dictionary<int, Item> items;
		Dictionary<int, ExtendedItem> extItems;
		Dictionary<int, PendingChange> pendingChanges;
		Dictionary<int, Conflict> conflicts;

		string rootPath;

		public LizardTFItems()
		{
			items = new Dictionary<int, Item>();
			extItems = new Dictionary<int, ExtendedItem>();
			pendingChanges = new Dictionary<int, PendingChange>();
			conflicts = new Dictionary<int, Conflict>();
		}

		public void AddRange(Item[] items)
		{
			foreach (Item item in items)
			{
				Add(item);
			}
		}

		public void AddRange(ExtendedItem[] extItems)
		{
			foreach (ExtendedItem extItem in extItems)
			{
				Add(extItem);
			}
		}

		public void AddRange(PendingChange[] pendingChanges)
		{
			foreach (PendingChange pendingChange in pendingChanges)
			{
				Add(pendingChange);
			}
		}

		public void AddRange(Conflict[] conflicts)
		{
			foreach (Conflict conflict in conflicts)
			{
				Add(conflict);
			}
		}

		public void Add(Item item)
		{
			items[item.ItemId] = item;
		}

		public void Add(ExtendedItem extItem)
		{
			extItems[extItem.ItemId] = extItem;
			if (rootPath == null)
				rootPath = Path.GetDirectoryName(extItem.SourceServerItem);
			string path = Path.GetDirectoryName(extItem.SourceServerItem);
			if (path.Length < rootPath.Length)
				rootPath = path;
		}

		public void Add(PendingChange pendingChange)
		{
			pendingChanges[pendingChange.ItemId] = pendingChange;
		}

		public void Add(Conflict conflict)
		{
			conflicts[conflict.YourItemId] = conflict;
		}

		public string RootPath
		{
			get { return rootPath.Replace('\\', '/'); }
		}

		public TFInfoSet this[int itemId]
		{
			get
			{
				TFInfoSet result = new TFInfoSet();
				if (items.ContainsKey(itemId)) result.Item = items[itemId];
				if (extItems.ContainsKey(itemId)) result.ExtendedItem = extItems[itemId];
				if (pendingChanges.ContainsKey(itemId)) result.PendingChange = pendingChanges[itemId];
				if (conflicts.ContainsKey(itemId)) result.Conflict = conflicts[itemId];

				return result;
			}
		}

		public IEnumerable<TFInfoSet> Itemsets
		{
			get
			{
				foreach (KeyValuePair<int, Item> kvp in items)
				{
					yield return this[kvp.Key];
				}
			}
		}

		public IEnumerable<TFInfoSet> PendingItemsets
		{
			get
			{
				foreach (KeyValuePair<int, PendingChange> kvp in pendingChanges)
				{
					yield return this[kvp.Key];
				}
			}
		}

		public IEnumerable<TFInfoSet> ConflictItemsets
		{
			get
			{
				foreach (KeyValuePair<int, Conflict> kvp in conflicts)
				{
					yield return this[kvp.Key];
				}
			}
		}

		public IEnumerable<TFInfoSet> OutOfDateItemsets
		{
			get
			{
				foreach (KeyValuePair<int, ExtendedItem> kvp in extItems)
				{
					ExtendedItem extItem = kvp.Value;
					if (extItem.VersionLatest != extItem.VersionLocal && extItem.DeletionId == 0)
						if (extItem.VersionLocal!=0 || (extItem.ChangeType & ChangeType.Delete)==0)
							yield return this[kvp.Key];
				}
			}
		}

		public IEnumerable<TFInfoSet> GetDifferentVersionItemsets(int version)
		{
			foreach (KeyValuePair<int, ExtendedItem> kvp in extItems)
			{
				ExtendedItem extItem = kvp.Value;
				if (!(extItem.VersionLatest == extItem.VersionLocal && version==0) && 
					version < extItem.VersionLocal  || (version > extItem.VersionLocal && 
					extItem.VersionLatest != extItem.VersionLocal) && extItem.DeletionId == 0 &&
					extItem.VersionLocal!=0)
					yield return this[kvp.Key];
			}
		}

		public IEnumerable<TFInfoSet> AllItemsets
		{
			get
			{
				foreach (KeyValuePair<int, ExtendedItem> kvp in extItems)
				{
					yield return this[kvp.Key];
				}
			}
		}


		public bool IsOutOfDate(int itemId)
		{
			return (extItems.ContainsKey(itemId) && (extItems[itemId].VersionLocal != extItems[itemId].VersionLatest));
		}

		public bool IsConflicted(int itemId)
		{
			return conflicts.ContainsKey(itemId);
		}

		public bool IsPendingChange(int itemId)
		{
			return pendingChanges.ContainsKey(itemId);
		}
	}
}
